#ifndef _SOCKETSTREAM_HPP_
#define _SOCKETSTREAM_HPP_

#include "net/Socket.hpp"
#include "net/StreamSocket.hpp"

#include "stream/streambuf.hpp"
using namespace JHCPP::stream;
#include <istream>
#include <ostream>

NET_NAMESPACE_BEGIN

class CStreamSocketImpl;
class CSocketStreamBuf : public BufferedBidirectionalStreamBuf
{
public:
	CSocketStreamBuf(const CSocket& socket);
	~CSocketStreamBuf();

	CStreamSocketImpl* socketImpl() const;

protected:
	int readFromDevice(char* buffer, std::streamsize length);
	int writeToDevice(const char* buffer, std::streamsize length);

private:
	enum 
	{
		STREAM_BUFFER_SIZE = 1024
	};

	CStreamSocketImpl* m_pImpl;
};


class CSocketIOS : public virtual std::ios
{
public:
	CSocketIOS(const CSocket& socket);
	~CSocketIOS();

	CSocketStreamBuf* rdbuf();
	void close();
	CStreamSocket socket() const;

protected:
	CSocketStreamBuf m_buf;
};

class CSocketOutputStream : public CSocketIOS, public std::ostream
{
public:
	explicit CSocketOutputStream(const CSocket& socket);
	~CSocketOutputStream();
};

class CSocketInputStream : public CSocketIOS, public std::istream
{
public:
	explicit CSocketInputStream(const CSocket& socket);
	~CSocketInputStream();
};


class CSocketStream : public CSocketIOS, public std::iostream
{
public:
	explicit CSocketStream(const CSocket& socket);
	~CSocketStream();
};

NET_NAMESPACE_END

#endif
